package com.frank.libandroid;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.ViewGroup;

import androidx.activity.EdgeToEdge;
import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContract;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.ViewDataBinding;

import com.frank.libandroid.butterknife.ButterKnife;
import com.frank.libandroid.util.Bus;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class BaseActivity<V extends ViewDataBinding> extends AppCompatActivity implements Bus.Receiver {
    protected V mBinding;
    protected String TAG = this.getClass().getSimpleName();
    protected BaseActivity mActivity;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Bus.register(this);
        mActivity = this;
        Log.d(TAG, "onCreate() called with: savedInstanceState = [" + savedInstanceState + "]");

        Class<V> generic = (Class<V>) ReflectUtil.getGeneric(this, 0);
        try {
            Method method = generic.getMethod("inflate", LayoutInflater.class, ViewGroup.class, boolean.class);
            mBinding = (V) method.invoke(null, getLayoutInflater(), null, false);
            setContentView(mBinding.getRoot());
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            throw new RuntimeException(e);
        }
        EdgeToEdge.enable(this);
//        ViewCompat.setOnApplyWindowInsetsListener(mBinding.getRoot(), (v, insets) -> {
//            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
//            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
//            return insets;
//        });
        initView();
        initData();
    }

    @Override
    public void onStart() {
        super.onStart();
        Log.d(TAG, "onStart() called");
        boolean b = EventBus.getDefault().hasSubscriberForEvent(getClass());
        for (Method declaredMethod : getClass().getDeclaredMethods()) {
            Subscribe annotation = declaredMethod.getAnnotation(Subscribe.class);
            if (annotation != null) {
                b = true;
                break;
            }
        }
        if (b) {
            EventBus.getDefault().register(this);
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        Log.d(TAG, "onStop() called");
        EventBus.getDefault().unregister(this);
    }

    protected void refreshData() {

    }

    protected void initData() {
    }

    protected void initView() {
        ButterKnife.bind(this, mBinding.getRoot());
    }


    public void start(Class<?> clazz) {
        Intent starter = new Intent(this, clazz);
        startActivity(starter);
    }

    protected void start(Class<? extends Activity> clazz, Object param) {
        Intent starter = new Intent(this, clazz);
        DataStore.put(clazz.getName(), param);
        startActivity(starter);
    }

    Runnable runnable;
    ActivityResultContract<Intent, ActivityResult> contract = new ActivityResultContracts.StartActivityForResult();
    ActivityResultLauncher<Intent> intentActivityResultLauncher = registerForActivityResult(contract, result -> {
        if (runnable != null) {
            runnable.run();
        }
    });

    protected <T> T get() {
        return DataStore.remove(this.getClass().getName());
    }

    protected void startActivityForResult(Class<?> clazz, Runnable runnable) {
        Intent starter = new Intent(this, clazz);
        this.runnable = runnable;
        intentActivityResultLauncher.launch(starter);
    }

    @Override
    public void onMessage(Object... value) {

    }
}
